<template>
  <div class="flex direction-column height-100 bg-white position-relative">
    <div class="tools-box padding">
      <el-tooltip content="旋转方向" placement="left">
        <el-button class="button" @click="rotate">
          <img class="button-img" src="./icon-spin.png" alt="">
        </el-button>
      </el-tooltip>
      <el-tooltip content="新增车间" placement="left">
        <el-button class="button" @click="addWorkShop">
          <img class="button-img" src="./icon-work-shop.png" alt="">
        </el-button>
      </el-tooltip>
      <el-tooltip content="新增监测点" placement="left">
        <el-button class="button" @click="addMonitorPoint">
          <img class="button-img" src="./icon-monitor-point.png" alt="">
        </el-button>
      </el-tooltip>
      <el-tooltip content="监测点管理" placement="left">
        <el-button class="button" @click="managePoints">
          <img class="button-img" src="./icon-indicator-manage.png" alt="">
        </el-button>
      </el-tooltip>
      <el-tooltip content="模板下载" placement="left">
        <el-button class="button" @click="downloadTpl">
          <img class="button-img" src="./icon-download.png" alt="">
        </el-button>
      </el-tooltip>
      <el-tooltip content="导入监测点" placement="left">
        <el-button class="button" @click="importData" style="position: relative;">
          <img class="button-img" src="./icon-import.png" alt="">
          <input
            style="opacity: 0;z-index: 11;position: absolute;display: block;left:0;right:0;bottom:0;top: 0;"
            type="file" @change="onFileChange"
          >
        </el-button>
      </el-tooltip>
      <el-tooltip v-if="false" content="导出监测点" placement="left">
        <el-button class="button">
          <img class="button-img" src="./icon-export.png" alt="">
        </el-button>
      </el-tooltip>
    </div>
    <div class="tree-box" ref="drag-zoom">
      <vue-drag-zoom
        ref="dragZoom"
        :area-node="node"
        allow-zoom
        :range="0.2"
        :max-zoom="1.2"
        :min-zoom="0.2"
      >
        <vue-org-tree
          :data="treeData" :render-content="renderContent"
          :horizontal="horizontal"
          @on-node-click="onNodeClick"
        ></vue-org-tree>
      </vue-drag-zoom>
    </div>
    <monitor-point-modal
      ref="monitorPointModal" :modal-title="monitorPointTitle"
      :modal-data="monitorPoint" @save-success="onSaveSuccess"
    ></monitor-point-modal>
    <monitor-points-manage
      ref="monitorPointsManage" @on-close="reload"
      @edit-row="editRow" @del-row="delRow"
    ></monitor-points-manage>
  </div>
</template>

<script>
import VueOrgTree from 'vue2-org-tree'
import VueDragZoom from '@/components/vue-drag-zoom'
import 'vue2-org-tree/dist/style.css'
import { uuid, confirmDel } from '@/utils'
import MonitorPointModal from '@/views/collection-method/monitor-point-modal'
import { selectPointList, saveOrUpdate, del as delWorkShop } from '@/api/point'
import { selectIndicatorList, del as delMonitorPoint, exportTemplateList, importIndicatorList } from '@/api/indicator'
import MonitorPointsManage from '@/views/collection-method/monitor-points-manage'

const api = {
  saveWorkShop: saveOrUpdate,
  queryWorkShop: selectPointList,
  queryMonitorPoint: selectIndicatorList,
  delWorkShop,
  delMonitorPoint,
  importIndicatorList,
  exportTemplateList,
}

export default {
  name: 'collection-method',
  components: {
    VueOrgTree,
    VueDragZoom,
    MonitorPointModal,
    MonitorPointsManage,
  },
  data () {
    return {
      node: null,
      horizontal: false,
      treeData: {},
      treeRoot: {},
      monitorPointTitle: '',
      monitorPoint: {},
    }
  },
  mounted () {
    this.node = this.$refs['drag-zoom']
    this.reload()
  },
  methods: {
    rotate () {
      this.horizontal = !this.horizontal
    },
    managePoints () {
      this.$refs.monitorPointsManage.open()
    },
    reload () {
      this.queryWorkShop().then(data => {
        data = Array.isArray(data) ? data[0] : {}
        const { children, ...rest } = data
        this.treeRoot = { ...rest }
        const codes = (children || []).map(v => v.pointCode)

        if (codes.length === 0) {
          this.initTreeStructure()
        } else {
          this.treeData = {
            ...this.treeRoot,
          }
          this.queryMonitorPoint(codes).then((points) => {
            this.makeTreeData(children, points)
          })
        }
      }).catch(() => {})
    },
    initTreeStructure () {
      const treeRoot = this.treeRoot
      const fakeWorkShop1 = {
        pointCode: uuid(),
        pointName: '车间#1',
        label: '车间#1',
        superiorPointCode: treeRoot.pointCode,
      }
      const fakeWorkShop2 = {
        pointCode: uuid(),
        pointName: '车间#2',
        label: '车间#2',
        superiorPointCode: treeRoot.pointCode,
      }
      this.treeData = {
        ...this.treeRoot,
        children: [
          fakeWorkShop1,
          fakeWorkShop2
        ],
      }
      this.saveWorkShop(fakeWorkShop1)
      this.saveWorkShop(fakeWorkShop2)
      this.reload()
    },
    renderContent (h, data) {
      // eslint-disable-next-line
      const horizontal = this.horizontal
      const isTreeRoot = this.isTreeRoot(data)
      const isWorkShop = this.isWorkShop(data)
      const isMonitorPoint = this.isMonitorPoint(data)
      if (isTreeRoot || isWorkShop) {
        return h('span', {
          style: `
            display: inline-block;
            width: ${(horizontal || isTreeRoot) ? 'auto' : '15px'};
            white-spacing: ${horizontal ? 'nowrap' : 'normal'};
            word-wrap: break-word;
          `,
          on: {
            contextmenu: (evt) => {
              evt.preventDefault()
              const hasChildren = data.children && data.children.length > 0
              if (!hasChildren) {
                this.delWorkShop(data.id)
              }
            }
          },
        }, data.pointName)
      }

      const render = (name, value) => h(
        'li',
        {
          style: `
            list-style: none;
            padding: 5px 0;
            font-size: 12px;
            white-space: nowrap;
          `
        },
        [
          h('label', {
            style: `
              color: #999;
            `
          }, name + '：'),
          h('span', value),
        ]
      )
      if (isMonitorPoint) {
        return h(
          'el-popover',
          {
            props: {
              trigger: 'hover',
              placement: 'right',
            }
          },
          [
            h('ul', {
              style: `
                list-style: none;
                text-align: left;
                padding-left: 0;
                margin: 0;
              `,
            }, [
              render('监测点名称', data.indicatorName),
              render('监测点编码', data.indicatorCode),
              render('监测点类型', data.type)
            ]),
            h('div', {
              slot: 'reference',
              style: `
                width: ${horizontal ? 'auto' : '15px'};
                text-orientation: mixed;
                word-wrap: break-word;
                white-spacing: ${horizontal ? 'nowrap' : 'normal'}
              `,
              on: {
                contextmenu: (evt) => {
                  evt.preventDefault()
                  const hasChildren = data.children && data.children.length > 0
                  if (!hasChildren) {
                    this.delMonitorPoint(data.id)
                  }
                }
              }
            }, [
              h('span', {}, data.indicatorName),
            ])
          ]
        )
      }
    },
    makeTreeData (workShopData, monitorPoints) {
      const children = [...workShopData]
      children.forEach(v => {
        const pointCode = v.pointCode
        const target = monitorPoints.find(vv => vv.pointCode === pointCode)
        if (target) {
          v.children = [...target.list]
        }
      })
      this.treeData = {
        ...this.treeData,
        children,
      }
    },
    onNodeClick (e, data) {
      const isMonitorPoint = this.isMonitorPoint(data)
      if (isMonitorPoint) {
        this.monitorPoint = { ...data }
        this.monitorPointTitle = '编辑监测点'
        this.$nextTick(() => {
          this.$refs.monitorPointModal.open()
        })
      } else {
        this.prompt('工厂/车间名称', '编辑工厂/车间名称', ({ value }) => {
          const workShop = {
            pointCode: data.pointCode,
            pointName: value,
            superiorPointCode: data.superiorPointCode,
            id: data.id,
          }
          this.saveWorkShop(workShop).then(res => {
            if (res.code === 200) {
              this.reload()
            }
          })
        }, data.pointName)
      }
    },
    onSaveSuccess () {
      this.reload()
    },
    addWorkShop () {
      return this.prompt('车间名称', '请输入车间名称', ({ value }) => {
        const workShop = {
          pointCode: uuid(),
          pointName: value,
          superiorPointCode: this.treeRoot.pointCode,
        }
        this.saveWorkShop(workShop).then(res => {
          if (res.code === 200) {
            this.reload()
          }
        })
      })
    },
    prompt (message, title, callback, inputValue) {
      this.$prompt(message, title, {
        confirmButtonText: '保存',
        cancelButtonText: '取消',
        inputPlaceholder: '首尾不能为空格，字数不超过6个',
        inputPattern: /^\S(.{0,4}\S)?$/,
        inputErrorMessage: '首尾不能为空格，字数不超过6个',
        inputValue,
        closeOnClickModal: false,
      }).then((obj) => {
        callback(obj)
      }).catch(() => {})
    },
    addMonitorPoint () {
      this.monitorPointTitle = '新增监测点'
      this.monitorPoint = {}
      this.$nextTick(() => {
        this.$refs.monitorPointModal.open()
      })
    },
    // 保存车间（点位）
    saveWorkShop (workShop) {
      return api.saveWorkShop(workShop)
    },
    // 获取车间（点位)
    queryWorkShop () {
      return new Promise((resolve, reject) => {
        api.queryWorkShop().then(res => {
          if (res.code === 200) {
            res.data.forEach(v => {
              v.label = v.pointName
            })
            resolve(res.data)
          } else {
            reject(new Error(res.code))
          }
        })
      })
    },
    // 删除车间（只能删除空车间）
    delWorkShop (id) {
      confirmDel(this).then(() => {
        api.delWorkShop(id).then(res => {
          if (res.code === 200) {
            this.reload()
          }
        })
      }).catch(() => {})
    },
    // 删除测点（指标）
    delMonitorPoint (id) {
      confirmDel(this).then(() => {
        api.delMonitorPoint(id).then(res => {
          if (res.code === 200) {
            this.reload()
          }
        })
      }).catch(() => {})
    },
    // 获取测点（指标）
    queryMonitorPoint (codes) {
      return new Promise((resolve, reject) => {
        api.queryMonitorPoint(codes).then(res => {
          if (res.code === 200) {
            resolve(res.data)
          } else {
            reject(new Error(res.code))
          }
        })
      })
    },
    isTreeRoot (node) {
      const treeRoot = this.treeRoot
      const pointTree = node.pointTree || ''
      return !!((treeRoot && node.pointCode === treeRoot.pointCode) || (pointTree && pointTree.length === 1))
    },
    isWorkShop (node) {
      const pointTree = (node.pointTree || '').split(',')
      return (!this.isTreeRoot(node)) && pointTree.length === 2
    },
    isMonitorPoint (node) {
      return !!node.indicatorCode
    },
    // 下载模板
    downloadTpl () {
      api.exportTemplateList()
    },
    // 导入数据
    onFileChange (evt) {
      const file = evt.target.files[0]
      console.log(file)
      api.importIndicatorList(file).then(res => {
        if (res.code === 200) {
          this.$message.success('导入成功')
        }
      })
    },
    importData () {},
    // 导出数据
    exportData () {},
    editRow (row) {
      this.monitorPoint = { ...row }
      this.monitorPointTitle = '编辑监测点'
      this.$nextTick(() => {
        this.$refs.monitorPointModal.open()
      })
    },
    delRow (row) {
      this.delMonitorPoint(row.id)
    },
  },
}
</script>

<style lang="scss" scoped>
.tree-box {
  flex: 1;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tools-box {
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  z-index: 11;
}
.button {
  display: block;
  margin: 1rem;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  background: #fff;
  box-shadow: 0 0 .7rem rgba(0,0,0,0.2);
}
.button-img {
  width: 20px;
  height: 20px;
}
</style>
